/****************************************************************
 * Implementation code for the 'Trip' class.
 * Homework 3, CSCE 240, Spring 2010
 * Author: Duncan Buell
 * Last Modified: 10 January 2010.
 *
 * The primary purpose of this code is to take as input a
 * sequence of trip data records, each trip having a number
 * of students 'studentCount' and a dollar amount for each
 * student, and then reallocating expenses so as to average the
 * expense for each student in a given trip.
 * Processing continues until a 0 appears for the number of
 * students.
**/
#include "Trip.h"

/****************************************************************
 * Default constructor.
**/
Trip::Trip()
{
}

/****************************************************************
 * Accessor for 'studentCount'.
 *
 * Arguments: None
 * Output: None
 * Returns: the value of 'studentCount'
**/
int Trip::getStudentCount()
{
  return studentCount;
}

/****************************************************************
 * Mutator for 'studentCount'.
 *
 * Arguments:
 *   what - the new value for 'studentCount'.
 * Output: None
 * Returns: None
**/
void Trip::setStudentCount(int what)
{
  studentCount = what;
}

/****************************************************************
 * The main 'doWork' function of the 'Trip' class. 
 *
 * We loop on input of 'studentCount' until we get a zero value.
 * Each nonzero value of 'studentCount' is a different trip.
 * We loop and input the dollars spent for that trip by each
 * student.  Finally, we compute how much money needs to change
 * hands in order for each student to have spent an equal amount,
 * and we compute in which directions money must change hands.
 *
 * Arguments:
 *   what - the new value for 'studentCount'.
 * Output:
 *   Logging information and echo of input data.
 *   Average expense per student.
 *   Total and individual amounts of money to be changing hands
 *     and in which directions.
 * Returns: None
**/
void Trip::doWork()
{
  enum { STUDENTFIELDWIDTH = 4};
  enum { DOLLARFIELDWIDTH = 8};
  enum { PRECISION = 2};
  double averageExpense; // Average expense per student.
  double totalChanging;  // Total amount changing hands this trip.
  double totalExpenses;  // Total expenses this trip.

  // Prime the loop on 'studentCount' until a zero input is found.
  cin >> studentCount;
  while(studentCount != 0)
  {
    if(studentCount < 0)
    {
      cout << "ERROR: student count " << studentCount
           << " is nonpositive\n";
      exit(0);
    }

    // Input the individual expenses and run a total.
    totalExpenses = 0;
    for(int i = 0; i < studentCount; ++i)
    {
      cin >> expenses[i];
      if(expenses[i] < 0)
      {
        cout << "ERROR: expense value " << expenses[i]
             << " is nonpositive\n";
        exit(0);
      }
      totalExpenses += expenses[i];
    } // for(int i = 0; i < studentCount; ++i)

    // Compute the average expense and total to change hands.
    averageExpense = totalExpenses/studentCount;
    totalChanging = 0;
    for(int i = 0; i < studentCount; ++i)
    {
      if(averageExpense > expenses[i])
      {
        totalChanging += averageExpense - expenses[i];
      }
    }

    // Echo the input and output the results.
    cout << "There were " << studentCount
         << " students and a total of $"
         << fixed << setw(DOLLARFIELDWIDTH)
         << setprecision(PRECISION)
         << totalExpenses << " spent\n";  
    cout << "The amounts to be adjusted are:\n";
    for(int i = 0; i < studentCount; ++i)
    {
      cout << "  Student " << setw(STUDENTFIELDWIDTH) << i
           << " $"
           << fixed << setw(DOLLARFIELDWIDTH) << setprecision(PRECISION)
           << abs(expenses[i] - averageExpense);
      if(expenses[i] <= averageExpense)
      {
        cout << " to be paid\n";
      }
      else
      {
        cout << " to be reimbursed\n";
      }
    }

    cout << "Total amount to change hands is $"
         << fixed << setprecision(PRECISION)
         << totalChanging << endl;

    cin >> studentCount;
  } // while(studentCount != 0)

}
